package com.example.portlocalforward.service;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.portlocalforward.controller.model.SshTunnelRequest;
import com.example.portlocalforward.controller.model.SshTunnelResponse;
import com.example.portlocalforward.entity.SshTunnel;
import com.example.portlocalforward.repository.SshTunnelRepository;

import lombok.extern.slf4j.Slf4j;

/**
 * SSH隧道服务类
 * 负责管理SSH隧道信息
 * 
 * @author Generated
 * @version 1.0.0
 */
@Slf4j
@Service
@Transactional
public class SshTunnelService {

    @Autowired
    private SshTunnelRepository sshTunnelRepository;

    /**
     * 创建SSH隧道
     * 
     * @param sshTunnelRequest 隧道请求信息
     * @return 创建的隧道响应信息
     */
    @Transactional(rollbackFor = Exception.class)
    public SshTunnelResponse createTunnel(SshTunnelRequest sshTunnelRequest) {
        log.info("创建SSH隧道: {}", sshTunnelRequest.getName());
        
        // 检查主机地址和端口是否已存在
        if (isTunnelAndPortExists(sshTunnelRequest.getHost(), sshTunnelRequest.getPort(), null)) {
            throw new RuntimeException("隧道地址和端口组合已存在: " + sshTunnelRequest.getHost() + ":" + sshTunnelRequest.getPort());
        }
        
        SshTunnel sshTunnel = new SshTunnel();
        BeanUtils.copyProperties(sshTunnelRequest, sshTunnel);
        
        SshTunnel savedTunnel = sshTunnelRepository.save(sshTunnel);
        return convertToResponse(savedTunnel);
    }

    /**
     * 根据ID获取隧道
     * 
     * @param id 隧道ID
     * @return 隧道响应信息
     */
    @Transactional(readOnly = true)
    public Optional<SshTunnelResponse> getTunnelById(Long id) {
        log.info("根据ID获取SSH隧道: {}", id);
        return sshTunnelRepository.findById(id).map(this::convertToResponse);
    }

    /**
     * 获取所有隧道
     * 
     * @return 隧道列表
     */
    @Transactional(readOnly = true)
    public List<SshTunnelResponse> getAllTunnels() {
        log.info("获取所有SSH隧道,按照创建时间倒序");
        return sshTunnelRepository.findAll(Sort.by(Sort.Direction.DESC, "createdTime")).stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
    }

    /**
     * 更新隧道信息
     * 
     * @param id 隧道ID
     * @param sshTunnelRequest 隧道请求信息
     * @return 更新后的隧道响应信息
     */
    @Transactional(rollbackFor = Exception.class)
    public SshTunnelResponse updateTunnel(Long id, SshTunnelRequest sshTunnelRequest) {
        log.info("更新SSH隧道: {}", id);
        
        // 检查隧道是否存在
        Optional<SshTunnel> existingTunnelOpt = sshTunnelRepository.findById(id);
        if (!existingTunnelOpt.isPresent()) {
            throw new RuntimeException("SSH隧道不存在，ID: " + id);
        }
        
        // 检查主机地址和端口是否被其他隧道占用
        if (isTunnelAndPortExists(sshTunnelRequest.getHost(), sshTunnelRequest.getPort(), id)) {
            throw new RuntimeException("主机地址和端口组合已被其他隧道占用: " + sshTunnelRequest.getHost() + ":" + sshTunnelRequest.getPort());
        }
        
        SshTunnel existingTunnel = existingTunnelOpt.get();
        
        // 只更新业务字段，保留时间字段
        existingTunnel.setName(sshTunnelRequest.getName());
        existingTunnel.setHost(sshTunnelRequest.getHost());
        existingTunnel.setPort(sshTunnelRequest.getPort());
        existingTunnel.setUsername(sshTunnelRequest.getUsername());
        existingTunnel.setPassword(sshTunnelRequest.getPassword());
        
        SshTunnel updatedTunnel = sshTunnelRepository.save(existingTunnel);
        return convertToResponse(updatedTunnel);
    }

    /**
     * 删除隧道
     * 
     * @param id 隧道ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteTunnel(Long id) {
        log.info("删除SSH隧道: {}", id);
        if (!sshTunnelRepository.existsById(id)) {
            throw new RuntimeException("SSH隧道不存在，ID: " + id);
        }
        sshTunnelRepository.deleteById(id);
    }

    /**
     * 根据隧道名称查找隧道
     * 
     * @param name 隧道名称
     * @return 隧道列表
     */
    @Transactional(readOnly = true)
    public List<SshTunnelResponse> findTunnelsByName(String name) {
        log.info("根据名称查找SSH隧道: {}", name);
        return sshTunnelRepository.findByNameContaining(name).stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
    }

    /**
     * 检查隧道地址和端口是否已存在
     * 
     * @param host 隧道地址
     * @param port 端口
     * @param excludeId 排除的隧道ID（用于更新时检查）
     * @return 是否已存在
     */
    @Transactional(readOnly = true)
    public boolean isTunnelAndPortExists(String host, int port, Long excludeId) {
        return sshTunnelRepository.findByHostAndPort(host, port).stream()
                .filter(tunnel -> !tunnel.getId().equals(excludeId))
                .findAny()
                .isPresent();
    }

    /**
     * 将实体转换为响应对象
     * 
     * @param sshTunnel 实体对象
     * @return 响应对象
     */
    private SshTunnelResponse convertToResponse(SshTunnel sshHost) {
        SshTunnelResponse response = new SshTunnelResponse();
        BeanUtils.copyProperties(sshHost, response);
        return response;
    }
}
